/*
 * Copyright 2012 The Eventio Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.eventio;

/**
 * The {@link EventDispatcher} controls event flow: it supports event
 * subscription and notification, and calls the registered reactions whenever a
 * event is triggered. The Dispatcher executes all reactions in a dedicated
 * {@link Thread}.
 * 
 * @author stephane.cusin
 * 
 */
public interface EventDispatcher {

	/**
	 * Emit an event, i.e. trigger all reactions, using the provided message as
	 * reaction input
	 * 
	 * @param event
	 *            the event to trigger
	 * @param message
	 *            the message to be reacted upon
	 */
	<T> void emit(Object event, T message);

	/**
	 * Subscribes this reaction to the given event. The reaction will be invoked
	 * whenever the event is triggered. Subscriptions can be canceled using
	 * {@link #remove(Object, Reaction)}
	 * 
	 * @param event
	 *            the event to subscribe to
	 * @param reaction
	 *            the reaction to be executed when the event arises
	 */
	<T> void on(Object event, Reaction<T> reaction);

	/**
	 * Same as {@link #on(Object, Reaction)}, except that the reaction will be
	 * invoked only once.
	 * 
	 * @param event
	 *            the event to subscribe to
	 * @param reaction
	 *            the reaction to be executed when the event arises
	 */
	<T> void once(Object event, Reaction<T> reaction);

	/**
	 * Removes reaction, if any. Reaction comparison is done by reference. If
	 * the reaction is present more than once, only the most recently added
	 * instance will be removed
	 * 
	 * @param event
	 *            the event to remove reactions from
	 * @param reaction
	 *            the reaction to be removed
	 */
	<T> void remove(Object event, Reaction<T> reaction);

	/**
	 * removes all reactions that correspond to this event
	 * 
	 * @param event
	 */
	void removeAll(Object event);

}
